/*
 * Copyright 2016-2017 lei.xu<xulei2008xulei@163.com>.
 *  
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *      http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.san21go.jfinfunc.jfinfunc.math;

import org.san21go.jfinfunc.AbstractFunction;
import org.san21go.jfinfunc.FinFuncRuntimeException;
import org.san21go.jfinfunc.math.covariance.COVARIANCEP;
import org.san21go.jfinfunc.math.stdev.STDEVP;

/**
 * CORREL 函数<br/>
 * 返回 Array1 和 Array2 单元格区域的相关系数。使用相关系数确定两个属性之间的关系。
 * 
 * @author xulei
 *
 */
public class CORREL extends AbstractFunction<Double> {

	private double[] value1s;
	private double[] value2s;

	public CORREL(double[] value1s, double[] value2s) {
		super();
		this.value1s = value1s;
		this.value2s = value2s;
	}

	@Override
	public Double evaluate() {

		if (value1s == null || value2s == null || value1s.length == 0) {
			throw new FinFuncRuntimeException("参数错误");
		}
		if (value1s.length != value2s.length) {
			throw new FinFuncRuntimeException("参数错误");
		}

		// double avg1 = new AVERAGE(value1s).evaluate();
		// double avg2 = new AVERAGE(value2s).evaluate();
		//
		// double ele = 0;
		// double den = 0;
		// for (int i = 0; i < value1s.length; i++) {
		// double value1 = value1s[i];
		// double value2 = value2s[i];
		// ele = ele + (value1 - avg1) * (value2 - avg2);
		// den = den + Math.pow((value1 - avg1), 2) * Math.pow((value2 - avg2),
		// 2);
		// }
		// if (Double.compare(den, 0) == 0) {
		// return 0D;
		// }
		// den = Math.sqrt(den);

		double ele = new COVARIANCEP(value1s, value2s).evaluate();
		double den = new STDEVP(value1s).evaluate() * new STDEVP(value2s).evaluate();
		double correl = 0D;
		if (Double.compare(den, 0D) != 0) {
			correl = ele / den;
		}
		return correl;
	}

}
